「迴圈」要在條件判斷為 true 時才會執行,例如 for 迴圈的:
for (int i = 0; i < 5; i++) {
printf( "%d ", i + 1);
}
要在「i 從 0 逐漸遞增到小於 5 」的條件為 true 時才會運行。
就像如下 while 迴圈中:
while(i <= 5) {
printf("%d ", i + 1);
i++;
}
的「i 小於或等於 5 」為 true 時才會運行。
而無窮迴圈指的是這個 for 或 while 的判斷條件永遠都不為 false,所以會一直運行下去。
不管是用哪種迴圈,要形成無窮迴圈的核心邏輯都是「讓判斷條件永遠不為 false」。
用 while 迴圈比較直覺,寫法如下:
while(1) {
printf("hello\n ");
}
這個 while 中的條件可以為任何真值(truthy value),因此不只可以為 1,還能為 -1、100、ptr 等等不為 0 者,或者更常見的 true。
do...while 無窮迴圈的寫法也差不多:
do {
printf("hello\n ");
} while (1);
C 語言最原始的無窮迴圈其實是用 for 迴圈表示,寫法如下:
for ( ; ; ) {
printf("hello\n ");
}
雖然 for 迴圈的括弧內項目為空看起來很怪,這卻是發明 C 語言的 K&R(Ken Thompson & Dennis Ritchie)兩人最推崇的寫法,代表不做任何判斷就直接運行 {} 當中的內容。
在部分程式碼檢查工具中,while(1) 這類寫法因為包含常數判斷,可能出現「常數表達(constant expression)」錯誤,也就是判斷條件永遠不變、跑不出迴圈,雖然這就是寫無窮迴圈時的目的,但此並非多數函數預期行為,因此會報錯;使用 for(;;) 就不會多這層判斷,可避免錯誤訊息產生。
另一種無窮迴圈的寫法是用 goto,如下:
Loop:
// ...
goto Loop;
goto 可以任意指定程式跳到哪邊執行,若發生錯誤將極難溯源、修復,造成維護負擔,因此現今多不建議使用。
加上 break 即可,例如:
while (1) {
...
if (跳出無窮迴圈的條件) break;
}
do {
...
if (跳出無窮迴圈的條件) break;
} while (1);
for (;;) {
...
if (跳出無窮迴圈的條件) break;
}
無窮迴圈會讓程式無止境運行下去、佔掉運算資源,那為何還要特別拿出來提呢?難不成它有什麼使用時機?
確實在某些情境中,我們會希望程式無限運行下去,直到某事件發生,例如:
while (1) {
int input;
printf("請輸入一個數字:");
scanf("%d", &input);
}
int main() {
while (1) {
int sensor = read_sensor(); // 讀取感測器資料
if (感測器讀取到什麼變化) {
// 要做什麼回應
}
}
}
while (1) {
int client = accept(server);
// 處理客戶端請求
close(client);
}
其他像背景程式、作業系統那些「隨時處於待命狀態,發生變化要做出應對」的項目,無窮迴圈都會派上用場。